scroll handlerを捨てよ、Intersection Observerへ出よう
https://gyazo.com/8ac7309a1b4012f3592a7c8bc2e086eb
自己紹介
yamanoku.icon @ yamanoku
おおやまみちのく a.k.a やまのく
既婚で1児の父と猫🐈🐈🐈の飼い主
マークアップ・フロントエンドエンジニア
https://gyazo.com/68a19f11b771c82a7887ede7791af040
Webアクセシビリティに関する本
今月3回目の登壇です
人様の前での登壇は人生で3回目です
scroll handler実装例
code:scroll.js
$(function(){
$(window).on('scroll', function(){
// some event
});
});
スクロール制御でつらいこと
スクロールイベントの発生は断続的なのでブラウザでの負荷がかかる
setTimeoutでゴニョゴニョする
レスポンシブ時で要素のスクロール位置がレイアウトによって変化する場合
レスポンシブで高さが変わる・SPだとレイアウトが縦長になる
1回のみの動作させるときはflag処理が必須
lazyloadなどの遅延読み込みをプラグインを使わずネイティブで分かりやすく出来ないか 日本語訳すると交点監視
https://gyazo.com/d26fc64bbcc8fade2c51604932c8c698
要素の出現によるものなので位置や高さの変動などを気にしなくてよい
監視自体を任意のタイミングでやめることもできるのでflag処理も不要
https://gyazo.com/7abca63e0ea4c032c8af819d3b155391 https://developers.google.com/search/docs/guides/lazy-loading
https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver
https://gyazo.com/2bd52198cc1e1ba91b6ae92269e98a39
コードサンプル
code:io.js
(() => {
const clientHeight = document.documentElement.clientHeight; // ブラウザ表示領域
const target = document.querySelector('.hoge'); // 監視対象の要素
const header = document.querySelector('.header');
const observer = new IntersectionObserver((changes) => { // Intersection Observerの設定
for (const change of changes) {
const rect = change.target.getBoundingClientRect();
const h = (0 < rect.top && rect.top < clientHeight) // 対象の上端は表示領域に入っている
|| (0 < rect.bottom && rect.bottom < clientHeight) // 対象の下端は表示領域に入っている
|| (0 > rect.top && rect.bottom > clientHeight); // 間が表示されている
if(h) { // 対象が表示されていないとき
header.classList.remove('scrolled'); // scorlledクラスを削除
} else { // 対象が表示されているとき
header.classList.add('scrolled'); // scorlledクラスを付与
}
}
});
observer.observe(target); // 監視開始
})();
特定のタイミングでヘッダー要素を変更するとき
https://gyazo.com/da422ec4777c54eda3b060cd1009d18a
あるセクションに来たらタイトルを取得してパンくずの切り替えするみたいな要望
https://gyazo.com/37bcf956627c8848fd6e964291a36de7
ページTOPボタンなどがフッターに到着した時に
https://gyazo.com/c146e3d691b188020d680a76c2b37e87
position: fixed => position: absolueに変更
カチッと止まるような演出
フッターが画面にあらわれた瞬間に発火
position: stickyでもいいんだろうけどJavaScript会なので yamanoku.icon 横スクロールもいけるんだろうか?
https://gyazo.com/4d24e017117aa54fb77f02a97299e44f
いけた yamanoku.icon
ほかにもObserverはある
Resize Observer
リサイズイベントを監視
resize eventはwindowのみの発火
対象はDOM単位でも動くのでtextareaとかでも動く https://gyazo.com/cacb53d8edf95f6de20107b697db0b78
window.matchMediaメソッドよりも汎用性ありそう
応用例(テキストチャット)
https://gyazo.com/ec169d17613f94eb844715fe6774d5e5
テキストチャットの大枠に overflow: scrollをつけて
Resize Observerでテキストチャットの中を監視して
親のscrollHeightとclientHeightの差分からスクロールを下部に移動
動的に追加されたのも監視できる
オプションいろいろ
childList:対象ノードの子ノードの追加・削除を監視
attributes:対象ノードの属性の変更を監視
characterData:テキストノードの変更を監視
subtree:対象ノードと子孫ノードを監視
attributeOldValue:対象ノードの属性の変更前の値を取得できるようにする
characterDataOldValue:対象テキストノードの変更前の値を取得できるようにする
attributeFilter:指定した属性のみ監視対象とする
https://gyazo.com/30beed0eb1626c4a085d4c6bc811c127 https://caniuse.com/#search=Mutation%20Observer
Obeserver API 関連リンク
yamanoku.icon どうでもいいんですが「Intersection Observer」でググると自分のQiita記事が上位に…(2018/11/20現在) https://gyazo.com/28ffa6d9b0847c4b151a9fe333a2f069
Let's Observer Life!
https://gyazo.com/7445b6198394060a4e49724fec2cb487